﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="VehicleRepositoryTest.cs" company="Concept Architecture">
//   (c) 2010 Muhammad Umer Farooq
// </copyright>
// <summary>
//   Defines the VehicleRepositoryTest type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Hisaab.Data.Tests
{
    using System.Data.Objects;
    using System.Linq;
    using Entities;
    using Interfaces;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using Moq;

    /// <summary>
    /// Defines the <seealso cref="Hisaab.Data.Tests.VehicleRepositoryTest"/> type.
    /// </summary>
    [TestClass]
    public class VehicleRepositoryTest
    {
        #region Vehicle Tests

        #region Query Tests

        /// <summary>
        /// Vehicles the data manager get Vehicles test with empty repository.
        /// </summary>
        [TestMethod]
        public void VehicleDataManagerQueryShouldReturnEmptyListWithEmptyRepository()
        {
            var mockObjectSet = new MockObjectSet<Vehicle>();
            var mockRepository = new Mock<IDatabase>();
            mockRepository.SetupGet(m => m.Vehicles).Returns(mockObjectSet);
            var dao = new VehicleRepository(mockRepository.Object);
            var result = dao.Query(new Vehicle(), null, null);
            Assert.IsNotNull(result);
            Assert.AreEqual(0, result.Count());
            mockRepository.VerifyAll();
        }

        /// <summary>
        /// Vehicles the data manager get Vehicles test with non empty repository.
        /// </summary>
        [TestMethod]
        public void VehicleDataManagerQueryShouldReturnNonEmptyListWithNonEmptyRepository()
        {
            var mockObjectSet = new MockObjectSet<Vehicle>();
            mockObjectSet.AddObject(new Vehicle { Id = 1, Title = "Vehicle 1" });
            mockObjectSet.AddObject(new Vehicle { Id = 2, Title = "Vehicle 2" });
            mockObjectSet.AddObject(new Vehicle { Id = 3, Title = "Vehicle 3" });
            var mockRepository = new Mock<IDatabase>();
            mockRepository.SetupGet(m => m.Vehicles).Returns(mockObjectSet);
            var dao = new VehicleRepository(mockRepository.Object);
            var result = dao.Query(new Vehicle(), null, null);
            Assert.IsNotNull(result);
            Assert.AreEqual(3, result.Count());
            Assert.AreEqual(1, result.ElementAt(0).Id);
            Assert.AreEqual("Vehicle 1", result.ElementAt(0).Title);
            Assert.AreEqual(2, result.ElementAt(1).Id);
            Assert.AreEqual("Vehicle 2", result.ElementAt(1).Title);
            Assert.AreEqual(3, result.ElementAt(2).Id);
            Assert.AreEqual("Vehicle 3", result.ElementAt(2).Title);
            mockRepository.VerifyAll();
        }

        #endregion Query Tests

        #region Filter Tests

        /// <summary>
        /// Vehicles the data manager get Vehicles test with empty repository.
        /// </summary>
        [TestMethod]
        public void VehicleDataManagerFilterShouldReturnEmptyListWithEmptyRepository()
        {
            var mockObjectSet = new MockObjectSet<Vehicle>();
            var mockRepository = new Mock<IDatabase>();
            mockRepository.SetupGet(m => m.Vehicles).Returns(mockObjectSet);
            var dao = new VehicleRepository(mockRepository.Object);
            var result = dao.Filter(x => true, null, null);
            Assert.IsNotNull(result);
            Assert.AreEqual(0, result.Count());
            mockRepository.VerifyAll();
        }

        /// <summary>
        /// Vehicles the data manager get Vehicles test with non empty repository.
        /// </summary>
        [TestMethod]
        public void VehicleDataManagerFilterShouldReturnNonEmptyListWithNonEmptyRepository()
        {
            var mockObjectSet = new MockObjectSet<Vehicle>();
            mockObjectSet.AddObject(new Vehicle { Id = 1, Title = "Vehicle 1" });
            mockObjectSet.AddObject(new Vehicle { Id = 2, Title = "Vehicle 2" });
            mockObjectSet.AddObject(new Vehicle { Id = 3, Title = "Vehicle 3" });
            var mockRepository = new Mock<IDatabase>();
            mockRepository.SetupGet(m => m.Vehicles).Returns(mockObjectSet);
            var dao = new VehicleRepository(mockRepository.Object);
            var result = dao.Filter(x => true, null, null);
            Assert.IsNotNull(result);
            Assert.AreEqual(3, result.Count());
            Assert.AreEqual(1, result.ElementAt(0).Id);
            Assert.AreEqual("Vehicle 1", result.ElementAt(0).Title);
            Assert.AreEqual(2, result.ElementAt(1).Id);
            Assert.AreEqual("Vehicle 2", result.ElementAt(1).Title);
            Assert.AreEqual(3, result.ElementAt(2).Id);
            Assert.AreEqual("Vehicle 3", result.ElementAt(2).Title);
            mockRepository.VerifyAll();
        }

        #endregion Filter Tests

        #region GetById Tests

        /// <summary>
        /// Get by id test with empty repository
        /// </summary>
        [TestMethod]
        public void VehicleDataManagerFindByIdShouldReturnNullWithEmptyRepository()
        {
            var mockObjectSet = new MockObjectSet<Vehicle>();
            var mockRepository = new Mock<IDatabase>();
            mockRepository.SetupGet(m => m.Vehicles).Returns(mockObjectSet);
            var dao = new VehicleRepository(mockRepository.Object);
            var result = dao.FindById(1);
            Assert.IsNull(result);
            mockRepository.VerifyAll();
        }

        /// <summary>
        /// Get by id test with repository with records
        /// </summary>
        [TestMethod]
        public void VehicleDataManagerFindByIdShouldReturnMatchingVehicle()
        {
            var mockObjectSet = new MockObjectSet<Vehicle>();
            mockObjectSet.AddObject(new Vehicle { Id = 1, Title = "Vehicle 1" });
            mockObjectSet.AddObject(new Vehicle { Id = 2, Title = "Vehicle 2" });
            mockObjectSet.AddObject(new Vehicle { Id = 3, Title = "Vehicle 3" });
            var mockRepository = new Mock<IDatabase>();
            mockRepository.SetupGet(m => m.Vehicles).Returns(mockObjectSet);
            var dao = new VehicleRepository(mockRepository.Object);
            var result = dao.FindById(2);
            Assert.IsNotNull(result);
            Assert.AreEqual(2, result.Id);
            Assert.AreEqual("Vehicle 2", result.Title);
            mockRepository.VerifyAll();
        }

        /// <summary>
        /// Vehicles the data manager find by id should return null with no matching Vehicle.
        /// </summary>
        [TestMethod]
        public void VehicleDataManagerFindByIdShouldReturnNullWithNoMatchingVehicle()
        {
            var mockObjectSet = new MockObjectSet<Vehicle>();
            mockObjectSet.AddObject(new Vehicle { Id = 1, Title = "Vehicle 1" });
            mockObjectSet.AddObject(new Vehicle { Id = 2, Title = "Vehicle 2" });
            mockObjectSet.AddObject(new Vehicle { Id = 3, Title = "Vehicle 3" });
            var mockRepository = new Mock<IDatabase>();
            mockRepository.SetupGet(m => m.Vehicles).Returns(mockObjectSet);
            var dao = new VehicleRepository(mockRepository.Object);
            var result = dao.FindById(20);
            Assert.IsNull(result);
            mockRepository.VerifyAll();
        }

        #endregion GetById Tests

        #region Insert Tests

        /// <summary>
        /// Email template dao insert test with empty repository
        /// </summary>
        [TestMethod]
        public void VehicleDataManagerInsertVehicleTestWithEmptyRepository()
        {
            var mockObjectSet = new MockObjectSet<Vehicle>();
            var mockRepository = new Mock<IDatabase>();
            mockRepository.SetupGet(m => m.Vehicles).Returns(mockObjectSet);
            mockRepository.Setup(m => m.SaveChanges());
            mockRepository.Setup(m => m.Refresh(RefreshMode.StoreWins, It.IsAny<Vehicle>()));
            var dao = new VehicleRepository(mockRepository.Object);
            var result = dao.Add(new Vehicle { Id = 1, Title = "Vehicle 1" });
            Assert.AreEqual(1, mockObjectSet.Count());
            Assert.IsNotNull(result);
            mockRepository.VerifyAll();
        }

        /// <summary>
        /// Email template dao insert test with existing records in repository
        /// </summary>
        [TestMethod]
        public void VehicleDataManagerInsertVehicleTestWithNonEmptyRepository()
        {
            var mockObjectSet = new MockObjectSet<Vehicle>();
            mockObjectSet.AddObject(new Vehicle { Id = 1, Title = "Vehicle 1" });
            var mockRepository = new Mock<IDatabase>();
            mockRepository.SetupGet(m => m.Vehicles).Returns(mockObjectSet);
            mockRepository.Setup(m => m.SaveChanges());
            mockRepository.Setup(m => m.Refresh(RefreshMode.StoreWins, It.IsAny<Vehicle>()));
            var dao = new VehicleRepository(mockRepository.Object);

            Assert.AreEqual(1, mockObjectSet.Count());

            var result = dao.Add(new Vehicle { Id = 2, Title = "Vehicle 2" });

            Assert.AreEqual(2, mockObjectSet.Count());
            Assert.IsNotNull(result);
            mockRepository.VerifyAll();
        }

        #endregion Insert Tests

        #region Udpate Tests

        /// <summary>
        /// Email template dao update test with no matching record
        /// </summary>
        [TestMethod]
        public void VehicleDataManagerUpdateVehicleTestWithNoMatchingRecord()
        {
            var mockObjectSet = new MockObjectSet<Vehicle>();
            mockObjectSet.AddObject(new Vehicle { Id = 1, Title = "Vehicle 1" });
            var mockRepository = new Mock<IDatabase>();
            mockRepository.SetupGet(m => m.Vehicles).Returns(mockObjectSet);
            var dao = new VehicleRepository(mockRepository.Object);
            dao.Update(new Vehicle { Id = 2, Title = "Vehicle 2" });

            Assert.AreEqual(1, mockObjectSet.Count());
            mockRepository.VerifyAll();
        }

        /// <summary>
        /// Email template dao update test with matching record
        /// </summary>
        [TestMethod]
        public void VehicleDataManagerUpdateVehicleTestWithMatchingRecord()
        {
            var mockObjectSet = new MockObjectSet<Vehicle>();
            mockObjectSet.AddObject(new Vehicle { Id = 1, Title = "Vehicle 1" });
            var mockRepository = new Mock<IDatabase>();
            mockRepository.SetupGet(m => m.Vehicles).Returns(mockObjectSet);
            mockRepository.Setup(m => m.SaveChanges()).Returns(1);

            var dao = new VehicleRepository(mockRepository.Object);
            dao.Update(new Vehicle { Id = 1, Title = "Vehicle 2" });

            Assert.AreEqual(1, mockObjectSet.Count());
            mockRepository.VerifyAll();
        }

        #endregion Udpate Tests

        #region Delete Tests

        /// <summary>
        /// Email template dao delete test with no matching record
        /// </summary>
        [TestMethod]
        public void VehicleDataManagerDeleteVehicleTestWithNoMatchingRecord()
        {
            var mockObjectSet = new MockObjectSet<Vehicle>();
            mockObjectSet.AddObject(new Vehicle { Id = 1, Title = "Vehicle 1" });
            var mockRepository = new Mock<IDatabase>();
            mockRepository.SetupGet(m => m.Vehicles).Returns(mockObjectSet);
            var dao = new VehicleRepository(mockRepository.Object);
            dao.Delete(new Vehicle { Id = 2 });

            Assert.AreEqual(1, mockObjectSet.Count());
        }

        /// <summary>
        /// Email template dao delete test with matching record
        /// </summary>
        [TestMethod]
        public void VehicleDataManagerDeleteVehicleTestWithMatchingRecord()
        {
            var mockObjectSet = new MockObjectSet<Vehicle>();
            mockObjectSet.AddObject(new Vehicle { Id = 1, Title = "Vehicle 1" });
            var mockRepository = new Mock<IDatabase>();
            mockRepository.SetupGet(m => m.Vehicles).Returns(mockObjectSet);
            var dao = new VehicleRepository(mockRepository.Object);
            dao.Delete(new Vehicle { Id = 1 });

            Assert.AreEqual(0, mockObjectSet.Count());
        }

        #endregion Delete Tests

        #endregion Vehicle Tests
    }
}